package com.example.drawboard.view;

import android.content.Context;
import android.graphics.*;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import androidx.core.graphics.ColorUtils;

import java.util.ArrayList;
import java.util.List;

public class ColorPicker extends View {

    private  GestureDetector gestureDetector;
    private int radius,height,width;
    private Paint paintLine;

    private float scale = (float) (144 * Math.PI/180);

    private Paint mCenterPaint;

    private int mInitialColor = Color.BLACK;//初始颜色

    private final int[] mColors = new int[] {//渐变色数组
            0xFFFF0000, 0xFFFF00FF, 0xFF0000FF, 0xFF00FFFF, 0xFF00FF00,
            0xFFFFFF00, 0xFFFF0000
    };

    private int paintColor;

    private float[] hsl_color = new float[3];

    private Paint mPaint,saturationPaint,lightnessPaint,indicatorPaint;

    public ColorPicker(Context context) {
        super(context);
    }

    public ColorPicker(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    public ColorPicker(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init_paint();

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        //获取宽的测量模式
        int heightSize =  MeasureSpec.getSize(heightMeasureSpec);//测量值
        height= resolveSize(heightSize, heightMeasureSpec);
        int widthSize =  MeasureSpec.getSize(widthMeasureSpec);//测量值
        width= resolveSize(widthSize, widthMeasureSpec);
        if(height <200) height = 200;
        if(width < 200) width = 200;
        radius = (width < height? width/2:height/2) - 20;
        setMeasuredDimension(width,height);
    }

    private int[] getSaturation(float[] hsl_color){
        int[] colors =new int[10];
        float[] floatArray = new float[3];
        for (int i = 0 ;i <3 ;i++){
            floatArray[i] = hsl_color[i];
        }
        for(int i=0;i < 10;i++){
            floatArray[1] =((float) i)/9;
            colors[i] = ColorUtils.HSLToColor(floatArray);
        }
        return colors;
    }

    private float[] getPositionArray(float offset){
        float[] colorPosition = new float[10];
        for (int i=0;i < 10;i++) {
            colorPosition[i] = i * (((float)144) / 9) / 360f + offset;
        }
        return colorPosition;
    }

    private int[] getLightness(float[] hsl_color){
        int[] colors =new int[10];
        float[] floatArray = new float[3];
        for (int i = 0 ;i <3 ;i++){
            floatArray[i] = hsl_color[i];
        }
        for(int i=0;i < 10;i++){
            floatArray[2] =((float) i)/9;
            colors[i] = ColorUtils.HSLToColor(floatArray);
        }
        return colors;
    }

    public void setPaintColor(float[] hsl_color){
        this.hsl_color = hsl_color;
        this.mInitialColor = ColorUtils.HSLToColor(hsl_color);
        indicatorPaint.setColor(mInitialColor);
        mCenterPaint.setColor(mInitialColor);

        Shader saturation = new SweepGradient(0, 0, getSaturation(hsl_color), getPositionArray(0.55f));
        saturationPaint.setShader(saturation);


        Shader lightness = new SweepGradient(0, 0, getLightness(hsl_color), getPositionArray(0.05f));
        lightnessPaint.setShader(lightness);
        invalidate();
    }


    private void init_paint(){
        ColorUtils.colorToHSL(Color.BLACK,hsl_color);
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        Shader s = new SweepGradient(0, 0, mColors, null);
        mPaint.setShader(s);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeWidth(12);

        indicatorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        indicatorPaint.setStrokeWidth(2);

        //初始化中心园画笔
        mCenterPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mCenterPaint.setStrokeWidth(2);

        saturationPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        saturationPaint.setStrokeCap(Paint.Cap.ROUND);
        saturationPaint.setStyle(Paint.Style.STROKE);
        saturationPaint.setStrokeWidth(12);

        lightnessPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        lightnessPaint.setStrokeCap(Paint.Cap.ROUND);
        lightnessPaint.setStyle(Paint.Style.STROKE);
        lightnessPaint.setStrokeWidth(12);
        setPaintColor(hsl_color);
    }

    private float[] RectToPolar(float x,float y){
        float polar[] = new float[2];
        if(x == 0){
            if(y>0){
                polar[0] = (float) (Math.PI/2);
            }else {
                polar[0] = (float) (3 * Math.PI/2);
            }
            polar[1] = Math.abs(y);
        }else{
            if(x<0){
                polar[0] = (float) Math.atan(y/x) +(float)Math.PI;
            }else {
                if(y>=0){
                    polar[0] = (float) Math.atan(y/x);
                }else {
                    polar[0] = (float) Math.atan(y/x) +2 * (float) Math.PI;
                }
            }
            polar[1] = (float) Math.sqrt(x*x +y*y);
        }
        return polar;
    }

    private float[] PolarToRect(float[] polar){
        float[] rect = new float[2];
        rect[0] = (float) (polar[1] * Math.cos(polar[0]));
        rect[1] = (float) (polar[1] * Math.sin(polar[0]));
        return rect;
    }

    public int getColor(){
        return mInitialColor;
    }

    public float[] getHslColor(){
        return hsl_color;
    }

    private int mode = -1;
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction() & event.ACTION_MASK)
        {
            case MotionEvent.ACTION_DOWN:           // 第一个手指按下事件
                float[] r = RectToPolar(event.getX() - width/2,event.getY() - height/2);
                if(r[1]<(radius+radius/6) && r[1] >(radius - radius/6) ){
                    mode = 1;
                }else if(r[1]<(radius*2/3+radius/6) && r[1] >(radius*2/3 - radius/6)){
                    if(r[0] < Math.PI/2 || r[0]>3 * Math.PI/2){
                        mode = 3;
                    }else {
                        mode = 2;
                    }
                }
                break;
            case MotionEvent.ACTION_UP:
                mode = -1;

                break;
            case MotionEvent.ACTION_MOVE:
                float[] p = RectToPolar(event.getX() - width/2,event.getY() - height/2);
                switch (mode){
                    case 1:
                        hsl_color[0] =360 - (p[0] * 360) /(float) (Math.PI *2);
                        setPaintColor(hsl_color);
                        break;
                    case 2:
                        hsl_color[1] = (p[0] + (float) Math.PI/2 - 198 * (float)Math.PI/180)/scale;
                        if(hsl_color[1] > 1){
                            hsl_color[1] = 1;
                        }
                        if(hsl_color[1] < 0){
                            hsl_color[1] = 0;
                        }
                        setPaintColor(hsl_color);
                        break;
                    case 3:
                        if(p[0] > Math.PI){
                            hsl_color[2] =  (p[0] + (float) Math.PI/2 - 2*(float)Math.PI - 18 * (float)Math.PI/180)/scale;
                        }else {
                            hsl_color[2] =  (p[0] + (float) Math.PI/2 - 18 * (float)Math.PI/180)/scale;
                        }
                        if(hsl_color[2] > 1){
                            hsl_color[2] = 1;
                        }
                        if(hsl_color[2] < 0){
                            hsl_color[2] = 0;
                        }
                        setPaintColor(hsl_color);
                        break;
                }
                invalidate();
                break;
        }
        return true;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.translate(width/2,height/2);
        canvas.drawCircle(0, 0, radius , mPaint);
        canvas.drawCircle(0, 0, radius/3 ,mCenterPaint );
        float[] porlar = new float[2];
        porlar[0] = -2 * (float) Math.PI *(hsl_color[0]/(float) 360);
        porlar[1] = radius;
        canvas.drawCircle(PolarToRect(porlar)[0],PolarToRect(porlar)[1],12,mCenterPaint);
        int sl_radius = radius * 2/3;
        RectF oval = new RectF(-sl_radius ,-sl_radius, sl_radius, sl_radius);
        int[] colorArray = new int[]{Color.RED, Color.YELLOW, Color.BLUE, Color.GREEN};
        canvas.rotate(-90); //h
        canvas.drawArc(oval,18 ,144,false,lightnessPaint); //l
        canvas.drawArc(oval,198 ,144,false,saturationPaint);//v
        porlar[1] = sl_radius;
        porlar[0] = 2 * (float) Math.PI *((144 * hsl_color[2] + 18 )/(float) 360);
        canvas.drawCircle(PolarToRect(porlar)[0],PolarToRect(porlar)[1],12,mCenterPaint);
        porlar[0] = 2 * (float) Math.PI *((144 * hsl_color[1] + 198 )/(float) 360);
        canvas.drawCircle(PolarToRect(porlar)[0],PolarToRect(porlar)[1],12,mCenterPaint);
    }
}